/*
 * $Id: NetLink.cc,v 1.5 2005-12-28 14:52:24 bacon Exp $
 */

#ifdef __linux

#include <xpp/net/NetLink.h>
#include <xp/bas/memory.h>

#include <asm/types.h>
#include <linux/netlink.h>

namespace xpp
{
	namespace net
	{
		NetLink::NetLink (): Socket (RAW)
		{
		}

		NetLink::~NetLink ()
		{
		}

		int NetLink::open_with_type (int type)
		{
			int sndbuf = 32768;
			int rcvbuf = 32768;

			if (create_socket (
				PF_NETLINK, socket_type, type) == -1) return -1;

			if (xp_scksetopt (this->sckhnd, SOL_SOCKET,
				SO_SNDBUF, &sndbuf, xp_sizeof(sndbuf)) == -1) {
				close ();
				return -1;
			}

			if (xp_scksetopt (this->sckhnd, SOL_SOCKET,
				SO_RCVBUF, &rcvbuf, xp_sizeof(rcvbuf)) == -1) {
				close ();
				return -1;
			}

			struct sockaddr_nl local;
			xp_memset (&local, 0, xp_sizeof(local));
			local.nl_family = AF_NETLINK;
			local.nl_groups = 0;

			if (xp_sckbind(this->sckhnd, 
				(xp_sckadr_t*)&local, xp_sizeof(local)) == -1) {
				close ();
				return -1;
			}

			return 0;
		}


		/*
		int xxxx (int family, int type)
		{
			struct {
				struct nlmsghdr nlh;
				struct rtgenmsg g;
			} req;
			struct sockaddr_nl nladdr;


			xp_memset (&nladdr, 0, xp_sizeof(nladdr));
			nladdr.nl_family = AF_NETLINK;

			req.nlh.nlmsg_len = xp_sizeof(req);
			req.nlh.nlmsg_type = type;
			req.nlh.nlmsg_flags = NLM_F_ROOT | NLM_F_MATCH | NLM_F_REQUEST;
			req.nlh.nlmsg_pid = 0;
			req.nlh.nlmsg_seq = 0;
			req.g.rtgen_family= family;
	
			return xp_scksendto (
				this->sckhnd, (void*)&req,
				xp_sizeof(req), 0, 
				(xp_sckadr_t*)&nladdr, xp_sizeof(nladdr));
		}
		*/

	}
}

#endif
